package org.nf.box.web.interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;

import io.jsonwebtoken.JwtException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.nf.box.common.jwt.JwtUtils;
import org.nf.box.common.result.ResultVO;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.HandlerInterceptor;

/**
 * @author lzp
 * @date 2024/10/21
 *
 * Whenever the user wants to access a protected route or resource,
 * the user agent should send the JWT,
 * typically in the Authorization header using the Bearer schema.
 * The content of the header should look like the following:
 *
 * Authorization: Bearer <token>
 *
 */
public class TokenAuthInterceptor implements HandlerInterceptor {

    public static final String TOKEN_HEADER = "Authorization";
    public static final String TOKEN_PREFIX = "Bearer ";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
         //放行跨域的预检
         if("OPTIONS".equals(request.getMethod())) {
            System.out.println("预检请求...");
            return true;
         }
         //才行请求头获取验证的header
         String header = request.getHeader(TOKEN_HEADER);
         if(header != null) {
             //去除Bearer前缀
            String token = header.replace(TOKEN_PREFIX, "");
             try {
                 //验证token
                 JwtUtils.verify(token);
                 //如果校验通过则获取payload
                 Integer userId = JwtUtils.parseToken(token, "user", Integer.class);
                 //将id保存到请求作用域
                 request.setAttribute("user", userId);
                 return true;
             } catch (JwtException e) {
                 response(response, 10005, "无效Token或已失效");
                 return false;
             }
         }
         response(response, HttpStatus.UNAUTHORIZED.value(), "请登录");
         return false;
    }

    /**
     * 响应客户端
     * @param response
     * @param code
     * @param message
     * @throws Exception
     */
    private void response(HttpServletResponse response, Integer code, String message) throws Exception {
        ResultVO result = new ResultVO<>();
        result.setCode(code);
        result.setMessage(message);
        response.setContentType("application/json;charset=utf-8");
        String json = new ObjectMapper().writeValueAsString(result);
        response.getWriter().println(json);
    }
}